import { View } from '@tarojs/components';
import Taro, { getCurrentInstance } from '@tarojs/taro';
import { useCallback, useEffect, useMemo, useState } from 'react';
import {
  AtActivityIndicator,
  AtButton,
  AtModal,
  AtRadio,
  AtTextarea,
  AtTimeline,
  AtToast
} from 'taro-ui';
import { RadioOption } from 'taro-ui/types/radio';
import { useDispatch, useSelector } from 'react-redux';
import { TAssigneeUserInfo, TJobListItem, TUserInfo } from '../../types';
import { TStateType } from '../../redux/reducers';
import { EStatus, toStatusString } from '../../utils/index';
import * as ActionTypes from '../../redux/action/types';
import TopIcon, { EIcon, StatusIconTypeArray } from '../../components/top-icon/index.weapp';

import './index.scss';

type TTimeline = {
  title: string;
  content?: any[];
  icon?: string;
  color?: 'blue' | 'green' | 'red' | 'yellow';
};

const My = () => {
  const originData: TJobListItem[] = useSelector((state: TStateType) => state.jobList);
  const userInfo: TUserInfo = useSelector((state: TStateType) => state.userInfo);
  const assigneeUserInfo: TAssigneeUserInfo = useSelector(
    (state: TStateType) => state.assigneeUserInfo
  );
  const dispatch = useDispatch();
  const _id = getCurrentInstance().router!.params._id;
  const [isLoading, setIsLoading] = useState(true);
  const [isOpenDeleteModal, setIsOpenDeleteModal] = useState(false);
  const [isOpenToast, setIsOpenToast] = useState(false);
  const [currentJobListItem, setCurrentJobListItem] = useState<TJobListItem>();
  const [timeline, setimeline] = useState<TTimeline[]>();
  const [noteText, setNoteText] = useState('');
  const [errorMessage, setErrorMessage] = useState('');
  const [assigneeToValue, setAssigneeToValue] = useState<string>();
  // const [assigneeToName, setAssigneeToName] = useState<string>();
  const [assigneeOptions, setAssigneeOptions] = useState<RadioOption<string>[]>([
    { label: userInfo.nickName, value: userInfo.openId }
  ]);

  const onRenderTimeLine = useCallback((planItem: TJobListItem) => {
    const timelineArr = [
      {
        title: `no start - ${new Date(planItem.createDetials.time).toLocaleDateString()} ${new Date(
          planItem.createDetials.time
        ).toLocaleTimeString()}`,
        content: [`create by ${planItem.createDetials.createBy}`],
        color: 'blue'
      },
      {
        title: `in progress - ${new Date(
          planItem.inProgressDetials.time
        ).toLocaleDateString()} ${new Date(planItem.inProgressDetials.time).toLocaleTimeString()}`,
        content: [`modify by ${planItem.inProgressDetials.modifyBy}`],
        icon: 'clock',
        color: 'yellow'
      },
      {
        title: `resolved - ${new Date(
          planItem.resolvedDetials.time
        ).toLocaleDateString()} ${new Date(planItem.resolvedDetials.time).toLocaleTimeString()}`,
        content: [`modify by ${planItem.resolvedDetials.modifyBy}`],
        icon: 'loading-3',
        color: 'red'
      },
      {
        title: `ready - ${new Date(planItem.readyDetials.time).toLocaleDateString()} ${new Date(
          planItem.readyDetials.time
        ).toLocaleTimeString()}`,
        content: [`modify by ${planItem.readyDetials.modifyBy}`],
        icon: 'bell',
        color: 'green'
      },
      {
        title: `closed - ${new Date(planItem.closedDetials.time).toLocaleDateString()} ${new Date(
          planItem.closedDetials.time
        ).toLocaleTimeString()}`,
        content: [`modify by ${planItem.closedDetials.modifyBy}`],
        icon: 'check-circle',
        color: 'green'
      }
    ].splice(0, parseInt(planItem.status.toString()) + 1);
    setimeline(timelineArr as TTimeline[]);
  }, []);

  useEffect(() => {
    Taro.cloud.callFunction({
      name: 'getjoblistforid',
      data: {
        _id
      },
      success: function (res: any) {
        const currentPlan: TJobListItem = res.result.data[0];
        setCurrentJobListItem(currentPlan);
        setAssigneeToValue(currentPlan.assigneeOpenId);
        onRenderTimeLine(currentPlan);
        setNoteText(currentPlan.note);
        setIsLoading(false);
      },
      fail: function (res) {
        console.log(res);
      }
    });
  }, [_id, onRenderTimeLine]);

  const currentAssigneeOptions = useMemo(
    () => [
      { label: userInfo.nickName, value: userInfo.openId },
      { label: assigneeUserInfo.nickName, value: assigneeUserInfo.openId }
    ],
    [assigneeUserInfo.nickName, assigneeUserInfo.openId, userInfo.nickName, userInfo.openId]
  );

  useEffect(() => {
    if (currentJobListItem) {
      const newAssigneeOptions = currentAssigneeOptions.filter(
        item => item.value && item.value !== userInfo.openId
      );
      setAssigneeOptions([
        { label: userInfo.nickName, value: userInfo.openId },
        ...newAssigneeOptions
      ]);
    }
  }, [currentAssigneeOptions, currentJobListItem, userInfo.nickName, userInfo.openId]);

  const getNameByOptionValue = useCallback(
    (value: string) => assigneeOptions.filter(option => option.value === value)[0].label,
    [assigneeOptions]
  );

  const onChangePlanItem = useCallback(
    (planItem: TJobListItem) => {
      setCurrentJobListItem(planItem);
      const newData = [...originData];
      const index = newData.findIndex(item => planItem._id === item._id);
      if (index > -1) {
        const item = newData[index];
        newData.splice(index, 1, {
          ...item,
          ...planItem
        });
        dispatch({ type: ActionTypes.EDIT_SET_JOBLIST, payload: newData });
      } else {
        newData.push(planItem);
        dispatch({
          type: ActionTypes.EDIT_SET_JOBLIST,
          payload: newData
        });
      }
    },
    [dispatch, originData]
  );

  const onItemChange = useCallback(
    (planItem: TJobListItem) => {
      const planItemRemoveId = { ...planItem };
      delete planItemRemoveId._id;
      Taro.cloud.callFunction({
        name: 'updatejobInfo',
        data: {
          _id,
          userInfo: planItemRemoveId
        }
      });
      try {
        onChangePlanItem(planItem);
      } catch (errInfo) {
        console.log('Validate Failed:', errInfo);
      }
    },
    [_id, onChangePlanItem]
  );

  const onAssigneeChange = useCallback(
    (value: string) => {
      setAssigneeToValue(value);
      const assigneeToName = getNameByOptionValue(value);
      let planItem = {
        ...currentJobListItem!,
        assigneeTo: getNameByOptionValue(value),
        assigneeOpenId: value
      };
      Taro.cloud.callFunction({
        name: 'updatejobInfo',
        data: {
          _id,
          userInfo: {
            assigneeTo: assigneeToName,
            assigneeOpenId: value
          }
        }
      });
      try {
        onChangePlanItem(planItem);
      } catch (errInfo) {
        console.log('Validate Failed:', errInfo);
      }
    },
    [_id, currentJobListItem, getNameByOptionValue, onChangePlanItem]
  );

  const renderIcon = useCallback((item: TJobListItem) => {
    return <TopIcon type={EIcon.StatusIcon} name={StatusIconTypeArray[item.status]} size={35} />;
  }, []);

  const renderStatusBtnText = useCallback((status: EStatus) => {
    switch (status) {
      case EStatus.NoStart:
        return 'Start';
      case EStatus.InProgress:
        return 'Resolve';
      case EStatus.Resolved:
        return 'Ready for ZZ';
      case EStatus.Ready:
        return 'Close';
      case EStatus.Closed:
        return 'Closed';
      default:
        return '';
    }
  }, []);

  const statusChangeClick = useCallback(
    (status: EStatus) => {
      let planItem = { ...currentJobListItem!, status };
      switch (status) {
        case EStatus.InProgress:
          planItem = {
            ...planItem,
            inProgressDetials: { time: new Date(), modifyBy: userInfo.nickName }
          };
          break;
        case EStatus.Resolved:
          planItem = {
            ...planItem,
            resolvedDetials: { time: new Date(), modifyBy: userInfo.nickName }
          };
          break;
        case EStatus.Ready:
          planItem = {
            ...planItem,
            readyDetials: { time: new Date(), modifyBy: userInfo.nickName }
          };
          break;
        case EStatus.Closed:
          planItem = {
            ...planItem,
            closedDetials: { time: new Date(), modifyBy: userInfo.nickName }
          };
          break;
        default:
          break;
      }
      onItemChange(planItem);
      onRenderTimeLine(planItem);
    },
    [currentJobListItem, onItemChange, onRenderTimeLine, userInfo.nickName]
  );

  const textAreaonBlur = useCallback(() => {
    Taro.cloud.callFunction({
      name: 'updatejobInfo',
      data: {
        _id,
        userInfo: {
          note: noteText
        }
      }
    });
  }, [_id, noteText]);

  const onDeleteHandle = useCallback(() => {
    if (currentJobListItem?.openId === userInfo.openId) {
      setIsOpenDeleteModal(false);
      Taro.cloud.callFunction({
        name: 'deletejoblist',
        data: {
          _id
        },
        success: function () {
          setIsOpenToast(true);
          setIsOpenDeleteModal(false);
          setErrorMessage('delete the success.');
          Taro.navigateBack();
          Taro.cloud.callFunction({
            name: 'getjoblist',
            data: {
              openId: userInfo.openId
            },
            success: function (res: any) {
              dispatch({
                type: ActionTypes.RESOLVE_GET_JOBLIST,
                payload: res.result.data
              });
            },
            fail: function (res) {
              console.log(res);
            }
          });
        },
        fail: function (res) {
          console.log(res);
        }
      });
    } else {
      setIsOpenToast(true);
      setIsOpenDeleteModal(false);
      setErrorMessage('you do not have the permission!');
    }
  }, [_id, currentJobListItem?.openId, dispatch, userInfo.openId]);

  const isActionDisabled = useMemo(() => {
    if (currentJobListItem) {
      return (
        currentJobListItem!.status === EStatus.Closed ||
        (currentJobListItem!.status === EStatus.Ready &&
          currentJobListItem?.openId !== userInfo.openId)
      );
    }
    return true;
  }, [currentJobListItem, userInfo.openId]);

  return (
    <View>
      {isLoading ? (
        <AtActivityIndicator mode='center' content='Loading...' color='white' />
      ) : (
        <View className='plan'>
          <View className='plan-top'>
            <View className='plan-page-title'>Plan</View>
            <TopIcon
              type={EIcon.Action}
              name='delete'
              size={45}
              onClick={() => setIsOpenDeleteModal(true)}
            />
          </View>
          <View className='plan_hearder'>
            <View className='plan-action'>
              <View className='plan-name'>{currentJobListItem?.planName}</View>
              <View className='action-btn-status'>
                <AtButton
                  type='primary'
                  size='small'
                  disabled={isActionDisabled}
                  onClick={() => statusChangeClick(currentJobListItem!.status + 1)}
                >
                  {renderStatusBtnText(currentJobListItem!.status)}
                </AtButton>
              </View>
            </View>
            <View className='plan-status-icon'>
              <View className='plan-status'>
                status: {toStatusString(currentJobListItem!.status)}
              </View>
              {renderIcon(currentJobListItem!)}
            </View>
          </View>
          <AtTimeline pending items={timeline!} className='time-line' />
          <View className='note-content'>
            <View className='note-title'>
              note
              <TopIcon type={EIcon.Action} name='notepad' size={55} />
            </View>
            <AtTextarea
              value={noteText}
              onChange={value => {
                setNoteText(value);
              }}
              onBlur={() => textAreaonBlur()}
              height={200}
              maxLength={200}
              placeholder='Please add a note...'
              className='note-body'
            />
          </View>
          {currentJobListItem?.openId === userInfo.openId && (
            <View className='assignee-container'>
              <View className='note-title'>
                assignee to
                <TopIcon type={EIcon.Action} name='fenpei' size={55} className='assignee-icon' />
              </View>
              <AtRadio
                className='assignee-body'
                options={assigneeOptions}
                value={assigneeToValue}
                onClick={(value: string) => {
                  if (value !== assigneeToValue) {
                    onAssigneeChange(value);
                  }
                }}
              />
            </View>
          )}
          <AtModal
            isOpened={isOpenDeleteModal}
            cancelText='Cancel'
            confirmText='Ok'
            onClose={() => setIsOpenDeleteModal(false)}
            onCancel={() => setIsOpenDeleteModal(false)}
            onConfirm={() => onDeleteHandle()}
            content='are you sure you want to delete this plan?'
          />
          <AtToast
            isOpened={isOpenToast}
            text={errorMessage}
            onClose={() => {
              setIsOpenToast(false);
              setErrorMessage('');
            }}
          />
        </View>
      )}
    </View>
  );
};
export default My;
